﻿using System.Collections.Generic;
using MyFloridaHouse.libSvCommonUtilities;
using MyFloridaHouse.libSvUtilities;
using MyFloridaHouse.libSvOpenDistricts.Census;
using MyFloridaHouse.ServiceConn.DistrBldrSvcRef;
using System.Collections.ObjectModel;
using System;
using System.Runtime.InteropServices;
using System.IO;
using System.Text;

namespace MyFloridaHouse.libSvOpenDistricts.StorageIsolated
{
    public static class IsolatedStorageHelper
    {
        #region Census Geometry

        internal static DateTime GetCensusGeometryFileDate()
        {
            return IsolatedStorageManager.GetFileCreationTime(Constants.IsolatedSaveDirectoryName, Constants.IsolatedCensusGeometryFileName);
        }

        internal static bool SaveCensusGeometry(List<CensusGeometryNode> saveList)
        {
            if (saveList.Count <= 0)
            {
                return false;
            }
            else
            {
                // NOTE FOR FUTURE REFERENCE: Can't use xml serialization because list is so big (170MB) , had to roll my own
                //byte[] serializedData = SerializationManager.Serialize(saveList); // This used too much memory, caused outOfMemory error
                byte[] serializedData = ConvertCensusGeometryListForStorage(saveList);
                byte[] serializedAndCompressedData = CompressionManager.Compress(serializedData);
                return IsolatedStorageManager.SaveData(serializedAndCompressedData, Constants.IsolatedSaveDirectoryName, Constants.IsolatedCensusGeometryFileName);
            }
        }

        internal static List<CensusGeometryNode> LoadCensusGeometry()
        {
            byte[] serializedAndCompressedData = IsolatedStorageManager.LoadBinaryData(Constants.IsolatedSaveDirectoryName, Constants.IsolatedCensusGeometryFileName);
            byte[] serializedData = CompressionManager.DecompressToByteArray(serializedAndCompressedData);
            return ConvertCensusGeometryListFromStorage(serializedData);
        }

        private static byte[] ConvertCensusGeometryListForStorage(List<CensusGeometryNode> saveList)
        {
            byte[] serializedData = new byte[saveList.Count * CensusGeometryNode.CensusGeometryStorageNodeSize];
            int offset = 0;
            foreach (var node in saveList)
            {
                CensusGeometryNode.GetBytes(node, serializedData, offset);
                offset += CensusGeometryNode.CensusGeometryStorageNodeSize;
            }
            return serializedData;
        }

        private static List<CensusGeometryNode> ConvertCensusGeometryListFromStorage(byte[] sourceByteArray)
        {
            List<CensusGeometryNode> newNodeList = new List<CensusGeometryNode>();
            int offset = 0;
            while (offset < sourceByteArray.Length)
            {
                // prevent reading past the end of the buffer
                if ((offset + CensusGeometryNode.CensusGeometryStorageNodeSize) <= sourceByteArray.Length)
                {
                    newNodeList.Add(CensusGeometryNode.GetCensusGeometryNode(sourceByteArray, offset));
                }
                offset += CensusGeometryNode.CensusGeometryStorageNodeSize;
            }
            return newNodeList;
        }

        internal static void DeleteCensusGeometry()
        {
            IsolatedStorageManager.Deletefile(Constants.IsolatedSaveDirectoryName, Constants.IsolatedCensusGeometryFileName);
            return;
        }

        #endregion

        #region DistrictPlanTypes

        internal static DateTime GetDistrictPlanTypesFileDate()
        {
            return IsolatedStorageManager.GetFileCreationTime(Constants.IsolatedSaveDirectoryName, Constants.IsolatedDistrictPlanTypesFileName);
        }

        internal static bool SaveDistrictPlanTypes(ObservableCollection<DistrictPlanTypeDTO> saveList)
        {
            byte[] serializedData = SerializationManager.Serialize(saveList);
            byte[] serializedAndCompressedData = CompressionManager.Compress(serializedData);
            return IsolatedStorageManager.SaveData(serializedAndCompressedData, Constants.IsolatedSaveDirectoryName, Constants.IsolatedDistrictPlanTypesFileName);
        }

        internal static ObservableCollection<DistrictPlanTypeDTO> LoadDistrictPlanTypes()
        {
            byte[] serializedAndCompressedData = IsolatedStorageManager.LoadBinaryData(Constants.IsolatedSaveDirectoryName, Constants.IsolatedDistrictPlanTypesFileName);
            byte[] serializedData = CompressionManager.DecompressToByteArray(serializedAndCompressedData);
            return (ObservableCollection<DistrictPlanTypeDTO>)SerializationManager.Deserialize(typeof(ObservableCollection<DistrictPlanTypeDTO>), serializedData);
        }

        internal static void DeleteDistrictPlanTypes()
        {
            IsolatedStorageManager.Deletefile(Constants.IsolatedSaveDirectoryName, Constants.IsolatedDistrictPlanTypesFileName);
            return;
        }
        #endregion
    }
}
